package com.such.kit.io.template.support;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map;
import org.apache.tools.ant.filters.StringInputStream;
import com.such.kit.io.simple.support.IOSimple;
import com.such.kit.string.StringCommons;
import com.such.kit.validate.ValidateCommons;

/**
 * @author SUCH
 * <pre>
 * [继承扩展于 {@link IOSimple}] 依赖模板的 IO 工具抽象类
 * 
 * 通过引入外部模板，可以不修改源代码更改 IO 特性
 * </pre>
 * @see IOSimple
 */
public abstract class IOTemplate extends IOSimple {

	/** templateIn：模板输入流，理论上来说所有类型的模板文件、数据都可以通过 InputStream 引入 */
	protected InputStream templateIn;

	/**
	 * <pre>
	 * 通过模板文件创建 {@link #templateIn}
	 * </pre>
	 * @param templatePath 模板文件路径
	 * @throws Exception
	 */
	public IOTemplate(String templatePath) throws Exception {
		this.templateIn = new FileInputStream(templatePath);
		initTemplate();
	}

	/**
	 * <pre>
	 * 通过模板字符串创建 {@link #templateIn}
	 * 
	 * [警告] 并不是所有类型的模板文件都可以通过字符串方式输入，如 excel 文件，可以根据实际情况进行 @deprecated 
	 * </pre>
	 * @param templateString 模板字符
	 * @param charset 字符集 [可空] [参考 {@link StringCommons}.ENCODE_*]
	 * @throws Exception
	 */
	public IOTemplate(String templateString, String charset) throws Exception {
		InputStream templateIn = null;
		if (ValidateCommons.isEmpty(charset)) {
			templateIn = new StringInputStream(templateString);
		} else {
			templateIn = new StringInputStream(templateString, charset);
		}
		this.templateIn = templateIn;
		initTemplate();
	}

	/**
	 * <pre>
	 * 通过 ByteArray 创建 {@link #templateIn}
	 * </pre>
	 * @param templateBytes 模板 ByteArray
	 * @throws Exception
	 */
	public IOTemplate(byte[] templateBytes) throws Exception {
		this.templateIn = new ByteArrayInputStream(templateBytes);
		initTemplate();
	}

	/**
	 * @param templateIn 模板输入流 [参考 {@link #templateIn}]
	 * @throws Exception
	 */
	public IOTemplate(InputStream templateIn) throws Exception {
		this.templateIn = templateIn;
		initTemplate();
	}
	
	@Override
	public abstract void setCharset(String charset);

	@Override
	public abstract void putArg(String key, Object value);

	@Override
	public abstract void putArgs(Map<String, Object> args);

	@Override
	public abstract void clearArgs();

	/**
	 * <pre>
	 * 初始化模板
	 * 根据不同的实现，重写 initTemplate 将 {@link #templateIn} 初始化为对应的 Config
	 * </pre>
	 * @throws Exception
	 */
	protected abstract void initTemplate() throws Exception;

}
